package com.woniuxy.patrol.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.utils.ResponseUtil;
import com.woniuxy.patrol.mapper.*;
import com.woniuxy.patrol.pojo.PatrolPlan;
import com.woniuxy.patrol.pojo.PatrolPointRecord;
import com.woniuxy.patrol.pojo.PatrolTask;
import com.woniuxy.patrol.pojo.PatrolTaskRoute;
import com.woniuxy.patrol.service.PatrolTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 巡更任务服务实现类
 */
@Service
@Slf4j
public class PatrolTaskServiceImpl extends ServiceImpl<PatrolTaskMapper, PatrolTask>
        implements PatrolTaskService {

    @Resource
    private PatrolTaskMapper taskMapper;
    @Resource
    private PatrolPlanMapper planMapper;
    @Resource
    private PatrolPlanRouteMapper planRouteMapper;
    @Resource
    private PatrolPointRecordMapper recordMapper;
    @Resource
    private PatrolRoutePointMapper routePointMapper;
    @Resource
    private PatrolTaskRouteMapper taskRouteMapper;

    @Override
    public PatrolTask getById(Long taskId) {
        if (taskId == null) {
            throw new IllegalArgumentException("任务ID不能为空");
        }
        return taskMapper.selectById(taskId);
    }

    /**
     * 生成巡更任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseUtil generateDailyTasks() {
        // 重置所有任务状态为0（未开始）
        resetAllTaskStatus();
        // 生成新任务
        LocalDate today = LocalDate.now();
        QueryWrapper<PatrolPlan> planQuery = new QueryWrapper<>();
        planQuery.eq("status", 1)
                .eq("is_delete", 1)
                .eq("plan_type", 1);
            List<PatrolPlan> validPlans = planMapper.selectList(planQuery);

        if (validPlans.isEmpty()) {
            return ResponseUtil.success("无启用的周期性巡更计划，今日无需生成任务");
        }

        int successCount = 0;
        for (PatrolPlan plan : validPlans) {
            QueryWrapper<PatrolTask> taskQuery = new QueryWrapper<>();
            taskQuery.eq("plan_id", plan.getPlanId())
                    .eq("task_date", today)
                    .eq("community_id", plan.getCommunityId())
                    .eq("is_delete", 1);
            if (taskMapper.selectCount(taskQuery) > 0) {
                continue;
            }

            PatrolTask task = new PatrolTask();
            task.setPlanId(plan.getPlanId());
            task.setPlanName(plan.getPlanName());
            task.setTaskDate(today);
            task.setTaskStatus(0);
            task.setCommunityId(plan.getCommunityId());
            task.setCommunityName(plan.getCommunityName());

            if (plan.getDailyStartTime() != null && plan.getDailyEndTime() != null) {
                task.setPlannedStartTime(LocalDateTime.of(today, plan.getDailyStartTime()));
                task.setPlannedEndTime(LocalDateTime.of(today, plan.getDailyEndTime()));
            } else {
                task.setPlannedStartTime(LocalDateTime.of(today, LocalTime.of(8, 0)));
                task.setPlannedEndTime(LocalDateTime.of(today, LocalTime.of(18, 0)));
            }

            List<Long> routeIds = planRouteMapper.selectRouteIdsByPlanId(plan.getPlanId());
            if (routeIds.isEmpty()) {
                continue;
            }
            task.setRouteIds(String.join(",", routeIds.stream().map(String::valueOf).toArray(String[]::new)));

            task.setExecutorId(plan.getExecutorId());
            task.setExecutorName(plan.getExecutorName());
            task.setCompletionRate(BigDecimal.ZERO);
            task.setIsDelete(1);
            task.setCreateBy("admin");
            task.setCreateTime(LocalDateTime.now());
            task.setUpdateTime(LocalDateTime.now());

            taskMapper.insert(task);
            Long taskId = task.getTaskId();

            List<PatrolTaskRoute> taskRoutes = new ArrayList<>();
            for (Long routeId : routeIds) {
                PatrolTaskRoute taskRoute = new PatrolTaskRoute();
                taskRoute.setTaskId(taskId);
                taskRoute.setRouteId(routeId);
                taskRoute.setStatus(0);
                taskRoute.setIsDelete(1);
                taskRoute.setCreateTime(LocalDateTime.now());
                taskRoutes.add(taskRoute);
            }
            taskRouteMapper.batchInsert(taskRoutes);

            successCount++;
        }

        return ResponseUtil.success("当日巡更任务生成完成，成功生成" + successCount + "条任务");
    }

    /**
     * 重置所有任务状态为0（未开始）
     */
    private void resetAllTaskStatus() {
        UpdateWrapper<PatrolTask> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("task_status", 0)
                .set("remark", null)
                .set("update_time", LocalDateTime.now());
        baseMapper.update(null, updateWrapper);
    }

    /**
 * 修改任务状态
 */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseUtil updateTaskStatus(Long taskId, Integer status, String remark) {
        PatrolTask task = getById(taskId);
        if (task == null || task.getIsDelete() == 0) {
            return ResponseUtil.error("任务不存在或已删除");
        }

        if (status < 0 || status > 5) {
            return ResponseUtil.error("无效的任务状态：0未开始/1进行中/2已完成/3已暂停/4已取消/5执行失败");
        }

        // 校验已完成状态的点位是否全部签到（保持原有逻辑）
        if (status == 2) {
            List<Long> routeIds = Arrays.stream(task.getRouteIds().split(","))
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
            int totalPoints = routePointMapper.countPointsByRouteIds(routeIds);

            QueryWrapper<PatrolPointRecord> recordQuery = new QueryWrapper<>();
            recordQuery.eq("task_id", taskId)
                    .eq("status", 1)
                    .eq("is_delete", 1)
                    .select("point_id")
                    .groupBy("point_id");

            List<Object> completedPointList = recordMapper.selectObjs(recordQuery);
            long completedPoints = completedPointList.size();

            if (completedPoints < totalPoints) {
                return ResponseUtil.error("存在未巡检点位，无法标记为已完成");
            }
        }

        // --------------------------
        // 核心修改：同步路线状态
        // --------------------------
        switch (status) {
            case 1:  // 任务变为进行中 → 路线状态改为巡检中
                syncTaskRouteStatus(taskId, 1);
                break;
            case 2:  // 任务变为已完成 → 路线状态改为已完成
                syncTaskRouteStatus(taskId, 2);
                break;
            case 0:  // 任务变为未开始 → 路线状态改为未巡检
            case 3:  // 任务暂停 → 路线状态改为未巡检
            case 4:  // 任务取消 → 路线状态改为未巡检
            case 5:  // 任务失败 → 路线状态改为未巡检
                syncTaskRouteStatus(taskId, 0);
                break;
        }

        // 更新任务状态（保持原有逻辑）
        switch (status) {
            case 1:
                task.setActualStartTime(LocalDateTime.now());
                break;
            case 2:
                task.setActualEndTime(LocalDateTime.now());
                calculateCompletionRate(taskId);
                break;
            case 3:
            case 4:
            case 5:
                task.setRemark(remark);
                break;
        }

        task.setTaskStatus(status);
        task.setUpdateBy("admin");
        task.setUpdateTime(LocalDateTime.now());
        task.setCompletionRate(BigDecimal.valueOf(100.00));// 更新完成度
        updateById(task);

        return ResponseUtil.success("任务状态已更新为：" + getStatusDesc(status));
    }

    /**
     * 获取当日任务列表
     * @param params 查询参数
     * @return 当日任务列表
     */
    @Override
    public List<PatrolTask> getTodayTasks(Map<String, Object> params) {
        LocalDate date = LocalDate.now();
        Integer status = (Integer) params.get("status");
        Long communityId = (Long) params.get("communityId");
        String keyword = (String) params.get("keyword");
        Integer page = (Integer) params.get("page");
        Integer pageSize = (Integer) params.get("pageSize");

        // 避免空指针：page默认1，pageSize默认10
        page = (page == null || page < 1) ? 1 : page;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        Integer offset = (page - 1) * pageSize;

        return taskMapper.selectByCondition(date, status, communityId, keyword, offset, pageSize);
    }

    // 实现统计任务总数的方法
    @Override
    public long countTodayTasks(Map<String, Object> params) {
        LocalDate date = LocalDate.now();
        Integer status = (Integer) params.get("status");
        Long communityId = (Long) params.get("communityId");
        String keyword = (String) params.get("keyword");

        return taskMapper.countByCondition(date, status, communityId, keyword);
    }

    /**
     * 统计今天任务数
     */
    @Override
    public int countTodayTasks(Long communityId) {
        QueryWrapper<PatrolTask> query = new QueryWrapper<>();
        query.eq("community_id", communityId)
                .eq("is_delete", 1)
                .ge("planned_start_time", LocalDate.now().atStartOfDay())
                .le("planned_end_time", LocalDate.now().atTime(23, 59, 59));
        return Math.toIntExact(baseMapper.selectCount(query));
    }

    /**
     * 计算今天已完成的任务数
     */
    @Override
    public int countTodayCompletedTasks(Long communityId) {
        QueryWrapper<PatrolTask> query = new QueryWrapper<>();
        query.eq("community_id", communityId)
                .eq("task_status", 2)
                .eq("is_delete", 1)
                .ge("planned_start_time", LocalDate.now().atStartOfDay())
                .le("planned_end_time", LocalDate.now().atTime(23, 59, 59));
        return Math.toIntExact(baseMapper.selectCount(query));
    }

    /**
     * 计算完成率
     */
    @Override
    public ResponseUtil calculateCompletionRate(Long taskId) {
        PatrolTask task = getById(taskId);

        if (task == null) {
            log.error("计算完成率失败，任务不存在，taskId={}", taskId);
            return ResponseUtil.error("任务不存在");
        }

        if (task.getIsDelete() == 0) {
            log.error("计算完成率失败，任务已删除，taskId={}", taskId);
            return ResponseUtil.error("任务已被删除");
        }

        String routeIds = task.getRouteIds();
        if (routeIds == null || routeIds.isEmpty()) {
            log.warn("任务未关联路线，taskId={}", taskId);
            task.setCompletionRate(BigDecimal.ZERO);
            updateById(task); // 只有这种情况需要单独更新
            return ResponseUtil.error("任务未关联路线，完成率：0%");
        }

        List<Long> routeIdList = Arrays.stream(routeIds.split(","))
                .map(Long::valueOf)
                .collect(Collectors.toList());
        int totalPoints = routePointMapper.countPointsByRouteIds(routeIdList);

        if (totalPoints == 0) {
            log.warn("任务关联的路线没有点位，taskId={}", taskId);
            task.setCompletionRate(BigDecimal.ZERO);
            updateById(task); // 只有这种情况需要单独更新
            return ResponseUtil.error("任务无关联点位，完成率：0%");
        }

        long completedPoints = recordMapper.countDistinctCompletedPoints(taskId);
        log.info("计算完成率：taskId={}, 总点位={}, 已完成={}", taskId, totalPoints, completedPoints);

        // 计算完成率
        BigDecimal completionRate = new BigDecimal(completedPoints)
                .divide(new BigDecimal(totalPoints), 4, RoundingMode.HALF_UP)
                .multiply(new BigDecimal(100));

        log.info("计算出的完成率值：{}", completionRate);

        // 确保完成率不超过100%
        if (completionRate.compareTo(new BigDecimal(100)) > 0) {
            completionRate = new BigDecimal(100);
        }

        task.setCompletionRate(completionRate);
        // 完成率100%自动标记为已完成
        if (completionRate.compareTo(new BigDecimal(100)) >= 0 && task.getTaskStatus() != 2) {
            task.setTaskStatus(2);
            task.setActualEndTime(LocalDateTime.now());
        }
        task.setUpdateTime(LocalDateTime.now());

        UpdateWrapper<PatrolTask> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("task_id", taskId)
                .set("completion_rate", completionRate)
                .set("task_status", task.getTaskStatus())
                .set("actual_end_time", task.getActualEndTime())
                .set("update_time", LocalDateTime.now());

        boolean updateResult = update(null, updateWrapper);
        log.info("更新完成率结果：taskId={}, 完成率={}%, 更新成功={}",
                taskId, completionRate.setScale(2, RoundingMode.HALF_UP), updateResult);

        return ResponseUtil.success("完成率计算成功：" + completionRate.setScale(2, RoundingMode.HALF_UP) + "%");
    }
    /**
     * 定时检查并更新过期任务
     */
    @Override
    public void checkAndUpdateExpiredTasks() {
        LocalDateTime now = LocalDateTime.now();
        QueryWrapper<PatrolTask> query = new QueryWrapper<>();
        query.le("planned_end_time", now)
                .notIn("task_status", 2,4) // 不包括已完成和失败的任务
                .eq("is_delete", 1);

        List<PatrolTask> expiredTasks = taskMapper.selectList(query);
        for (PatrolTask task : expiredTasks) {
            task.setTaskStatus(5);
            task.setRemark("系统自动标记：任务逾期未完成");
            task.setUpdateTime(LocalDateTime.now());
        }
        updateBatchById(expiredTasks);
    }
    /**
     * 获取任务统计信息
     *
     * @param date      统计日期，默认为当前日期
     * @param communityId 社区ID
     * @return 任务统计信息
     */
    @Override
    public ResponseUtil getTaskStats(LocalDate date, Long communityId) {
//        LocalDate statsDate = date == null ? LocalDate.now() : date;
//        LocalDateTime startOfDay = statsDate.atStartOfDay();
//        LocalDateTime endOfDay = statsDate.atTime(LocalTime.MAX);

        LambdaQueryWrapper<PatrolTask> query = new LambdaQueryWrapper<>();
        query.eq(PatrolTask::getIsDelete, 1);
//        query.ge(PatrolTask::getPlannedStartTime, startOfDay)
//                .le(PatrolTask::getPlannedStartTime, endOfDay)
//                .eq(PatrolTask::getIsDelete, 1);
        if (communityId != null) {
            query.eq(PatrolTask::getCommunityId, communityId);
        }

        long total = count(query);
        long notStarted = count(query.clone().eq(PatrolTask::getTaskStatus, 0));
        long ongoing = count(query.clone().eq(PatrolTask::getTaskStatus, 1));
        long completed = count(query.clone().eq(PatrolTask::getTaskStatus, 2));
//        long paused = count(query.clone().eq(PatrolTask::getTaskStatus, 3));
//        long canceled = count(query.clone().eq(PatrolTask::getTaskStatus, 4));
        long failed = count(query.clone().eq(PatrolTask::getTaskStatus, 5));

        Map<String, Long> stats = new HashMap<>();
        stats.put("total", total);
        stats.put("notStarted", notStarted);
        stats.put("ongoing", ongoing);
        stats.put("completed", completed);
//        stats.put("paused", paused);
//        stats.put("canceled", canceled);
        stats.put("failed", failed);
        stats.put("unfinished", notStarted + ongoing + failed);//未完成

        return ResponseUtil.success(stats);
    }
//    @Override
//    public ResponseUtil getTaskStats(LocalDate date, Long communityId) {
//        LocalDate statsDate = date == null ? LocalDate.now() : date;
//        LocalDateTime startOfDay = statsDate.atStartOfDay();
//        LocalDateTime endOfDay = statsDate.atTime(LocalTime.MAX);
//
//        LambdaQueryWrapper<PatrolTask> query = new LambdaQueryWrapper<>();
//        query.ge(PatrolTask::getPlannedStartTime, startOfDay)
//                .le(PatrolTask::getPlannedStartTime, endOfDay)
//                .eq(PatrolTask::getIsDelete, 1);
//        if (communityId != null) {
//            query.eq(PatrolTask::getCommunityId, communityId);
//        }
//
//        long total = count(query);
//        query.eq(PatrolTask::getTaskStatus, 1);
//        long ongoing = count(query);
//        query.eq(PatrolTask::getTaskStatus, 2);
//        long completed = count(query);
//        query.eq(PatrolTask::getTaskStatus, 3);
//        long paused = count(query);
//        query.eq(PatrolTask::getTaskStatus, 4);
//        long canceled = count(query);
//        query.eq(PatrolTask::getTaskStatus, 5);
//        long failed = count(query);
//
//        Map<String, Long> stats = new HashMap<>();
//        stats.put("total", total);
//        stats.put("ongoing", ongoing);
//        stats.put("completed", completed);
//        stats.put("paused", paused);
//        stats.put("canceled", canceled);
//        stats.put("failed", failed);
//        stats.put("unfinished", total - completed);
//
//        return ResponseUtil.success(stats);
//    }


    @Override
    public ResponseUtil checkCanGenerateTodayTasks(Long communityId) {
        LocalDate today = LocalDate.now();
        QueryWrapper<PatrolTask> query = new QueryWrapper<>();
        query.eq("task_date", today)
                .eq("community_id", communityId)
                .eq("is_delete", 1);

        return ResponseUtil.success(count(query) == 0);
    }

    private String getStatusDesc(Integer status) {
        switch (status) {
            case 0: return "未开始";
            case 1: return "进行中";
            case 2: return "已完成";
            case 3: return "已暂停";
            case 4: return "已取消";
            case 5: return "执行失败";
            default: return "未知状态";
        }
    }
    /**
     * 同步任务关联的路线状态
     * @param taskId 任务ID
     * @param targetStatus 目标状态（0-未巡检，1-巡检中，2-已完成）
     */
    private void syncTaskRouteStatus(Long taskId, Integer targetStatus) {
        if (taskId == null || targetStatus == null
                || (targetStatus != 0 && targetStatus != 1 && targetStatus != 2)) {
            return; // 无效参数直接返回
        }

        // 更新该任务下所有路线的状态
        UpdateWrapper<PatrolTaskRoute> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("task_id", taskId)
                .eq("is_delete", 1)
                .set("status", targetStatus)
                .set("update_time", LocalDateTime.now());
        taskRouteMapper.update(null, updateWrapper);
    }

}